﻿using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

namespace GameToolkit
{
    [RequireComponent(typeof(MeshFilter))]
    [AddComponentMenu("Navigation/Runtime NavMeshFilter")]
    public class NavMeshFilterRT : NavMeshSource
    {
#pragma warning disable CS0649

        //[HideInInspector]
        [SerializeField]
        Vector3 m_Center;

        [SerializeField]
        Vector3 m_Size;
        //Bounds m_LocalBounds;

#pragma warning restore

        public override Bounds localBounds { get { return new Bounds(m_Center, m_Size); } }

        public Bounds CalculateLocalbounds()
        {
            var mesh = GetComponent<MeshFilter>();
            if (mesh.sharedMesh == null)
                return default;
            else
                return GeometryUtility.CalculateBounds(mesh.sharedMesh.vertices, Matrix4x4.identity);
        }

        [ContextMenu("Recalculate Bounds")]
        public void RecalulateBounds()
        {
            var bounds = CalculateLocalbounds();
            var size = bounds.size;
            var center = bounds.center;
            size.x = Mathf.Max(size.x, 0.00001f);
            size.y = Mathf.Max(size.y, 0.00001f);
            size.z = Mathf.Max(size.z, 0.00001f);
            if (!Mathf.Approximately(Vector3.SqrMagnitude(center - m_Center), 0) ||
                !Mathf.Approximately(Vector3.SqrMagnitude(size - m_Size), 0))
            {
                m_Center = center;
                m_Size = size;
#if UNITY_EDITOR
                UnityEditor.EditorUtility.SetDirty(this);
#endif
            }
        }

        public override void GetBuildSource(int areaType, ICollection<NavMeshBuildSource> sources)
        {
            //if (m_IsModifyBox)
            //{
            //    var mcenter = transform.TransformPoint(m_Center);
            //    var scale = transform.lossyScale;
            //    var msize = new Vector3(m_Size.x * Mathf.Abs(scale.x), m_Size.y * Mathf.Abs(scale.y), m_Size.z * Mathf.Abs(scale.z));

            //    var src = new NavMeshBuildSource();
            //    src.shape = NavMeshBuildSourceShape.ModifierBox;
            //    src.transform = Matrix4x4.TRS(mcenter, transform.rotation, Vector3.one);
            //    src.size = msize;
            //    src.area = m_AreaType;
            //    sources.Add(src);
            //}
            //else
            //{
            MeshFilter mesh;
            if (!TryGetComponent(out mesh) || mesh.sharedMesh == null)
                return;
            var src = new NavMeshBuildSource();
            src.shape = NavMeshBuildSourceShape.Mesh;
            src.area = this.areaType == 0 ? areaType : this.areaType;
            src.sourceObject = mesh.sharedMesh;
            src.transform = transform.localToWorldMatrix;
            sources.Add(src);
            //}
        }

#if UNITY_EDITOR

        private void OnValidate()
        {
            if (Mathf.Approximately(m_Size.x * m_Size.y * m_Size.z, 0))
                RecalulateBounds();
        }

        private void OnDrawGizmosSelected()
        {
            Gizmos.matrix = transform.localToWorldMatrix;
            Gizmos.color = Color.gray * 0.8f;
            var bd = localBounds;
            Gizmos.DrawWireCube(bd.center, bd.size);
        }
#endif

    }
}